﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;


namespace NZBMatrixAdvancedFeedReader
{
    public partial class frmMain : Form
    {

        #region Constructor

        public frmMain()
        {

            InitializeComponent();

            _BindingSource = new BindingSource();
            
            //BindControls();
        }

        #endregion

        #region Event Handlers

        private void frmMain_Load(object sender, EventArgs e)
        {

            _LastRefresh = DateTime.Now;

            //  Populate the Templates
            PopulateTemplatesSubMenus();

            //  Setup Timer
            SetupRefreshTimer();

            //  Check the refresh period
            if (Classes.SystemSettings.RefreshPeriod >= 20)
                tmrAutoRefresh.Start();


        }

        private void tsmiSettingsEditTemplate_Click(object sender, EventArgs e)
        {
            frmSearchTemplateMaintenance frm;
            frm = new frmSearchTemplateMaintenance();
            frm.ShowDialog();
            frm.Dispose();

            PopulateTemplatesSubMenus();

        }

        private void tsmiSettingsSettings_Click(object sender, EventArgs e)
        {
            frmSettings frm = new frmSettings();
            frm.ShowDialog();
        }

        private void tsmiSettingsExit_Click(object sender, EventArgs e)
        {
            Application.Exit();
        }

        private void tsmiAbout_Click(object sender, EventArgs e)
        {
            frmAbout frm = new frmAbout();
            frm.ShowDialog();
        }

        private void tsbManualRefresh_Click(object sender, EventArgs e)
        {
            if (_LoadingData)
            {
                _SearchThread.Abort();

                UpdateSearchButtonState(true);
                //  Last command records the Last Refresh DateTime
                _LastRefresh = DateTime.Now;
                //  Resume timer to previous state.
                tmrAutoRefresh.Enabled = true;

            }
            else
                RefreshData();
        }

        private void myTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
        {
            if (decimal.Parse(tsddbRefreshPeriod.Text) > 0)
            {
                DateTime nextRefreshTime;
                double remainingSecond;

                if (!_LastRefresh.HasValue)
                    _LastRefresh = DateTime.Now;

                nextRefreshTime = _LastRefresh.Value.AddMinutes(Classes.SystemSettings.RefreshPeriod);
                remainingSecond = (nextRefreshTime - DateTime.Now).TotalSeconds;

                UpdateToolStripText(tslNextRefesh,remainingSecond.ToString("0") + " seconds");

                if (remainingSecond <= 0)
                {
                    RefreshData();
                }
            }
        }

        private void tsmiSearchTemplate_Click(object sender, EventArgs e)
        {
            //  Load Particular Search Template
            ToolStripMenuItem tsmi = sender as ToolStripMenuItem;
            Classes.SystemSettings.SelectedTemplate = tsmi.Tag as Classes.SearchTemplate;
            Classes.SystemSettings.SaveSettings();

            foreach (var item in tsmiSearchTemplates.DropDownItems)
            {
                ((ToolStripMenuItem)item).Checked = false;
            }

            tsmi.Checked = true;
        }

        private void tsddbRefreshPeriod_DropDownClosed(object sender, EventArgs e)
        {
            int iTemp = 0;

            int.TryParse(tstRefreshPeriod.Text, out iTemp);

            if (iTemp < 20)
                iTemp = 0;

            Classes.SystemSettings.RefreshPeriod = iTemp;
            Classes.SystemSettings.SaveSettings();

            if (Classes.SystemSettings.RefreshPeriod == 0)
                tmrAutoRefresh.Stop();
            else
                tmrAutoRefresh.Start();

            tsddbRefreshPeriod.Text = iTemp.ToString();

        }

        private void tsddbRefreshPeriod_DropDownOpening(object sender, EventArgs e)
        {
            tstRefreshPeriod.Text = Classes.SystemSettings.RefreshPeriod.ToString();
        }

        private void tsmiStopTimer_Click(object sender, EventArgs e)
        {
            //  Set the timer to zero to stop it.
            tstRefreshPeriod.Text = "0";
            tsddbRefreshPeriod_DropDownClosed(tsddbRefreshPeriod, EventArgs.Empty);
        }

        #endregion

        #region Private Methods

        private string formatBytes(float bytes)
        {
            string[] Suffix = { "B", "KB", "MB", "GB", "TB" };
            int i;
            double dblSByte = 0;
            for (i = 0; (int)(bytes / 1024) > 0; i++, bytes /= 1024)
                dblSByte = bytes / 1024.0;
            return String.Format("{0:0.00} {1}", dblSByte, Suffix[i]);
        }

        private void SetupRefreshTimer()
        {
            tsddbRefreshPeriod.Text = Classes.SystemSettings.RefreshPeriod.ToString();
            tmrAutoRefresh.Elapsed += myTimer_Elapsed;
            tmrAutoRefresh.Interval = 1000;
            tmrAutoRefresh.Enabled = true;
            tmrAutoRefresh.Stop();

        }

        private void RefreshData()
        {
            if (!_LoadingData)
            {
                tmrAutoRefresh.Enabled = false;

                UpdateSearchButtonState(false);

                System.Threading.ThreadStart ts = new System.Threading.ThreadStart(RefreshDataThread);
                _SearchThread = new System.Threading.Thread(ts);
                _SearchThread.IsBackground = true;
                _SearchThread.Start();
            }
        }

        private void RefreshDataThread()
        {

            //  Create Feed Loader.
            Classes.FeedLoader feedLoader = new Classes.FeedLoader();
            List<Classes.MovieFeed> feedList;

            feedLoader.ProcessChanged += FeedLoader_ProcessChanged;

            feedLoader.SearchTemplate = Classes.SystemSettings.SelectedTemplate;
            feedList = feedLoader.LoadFeeds();

            UpdateDataIntoFlowLayoutPanel(feedList);

            UpdateSearchButtonState(true);

            //  Last command records the Last Refresh DateTime
            _LastRefresh = DateTime.Now;


            tmrAutoRefresh.Enabled = true;

        }

        private void UpdateSearchButtonState(bool searchFinished)
        {

            if (tsbManualRefresh.GetCurrentParent().InvokeRequired)
            {
                dlgUpdateSearchButton d = new dlgUpdateSearchButton(UpdateSearchButtonState);
                this.Invoke(d, new object[] { searchFinished });

            }
            else
            {
                if (searchFinished)
                {
                    tsbManualRefresh.Image = Properties.Resources.imgRefreshStatic;
                    _LoadingData = false;

                }
                else
                {
                    tsbManualRefresh.Image = Properties.Resources.imgRefreshDynamic;
                    _LoadingData = true;
                }
            }

        }

        private void UpdateDataIntoFlowLayoutPanel(List<Classes.MovieFeed> datasource)
        {
            if (flpMovies.InvokeRequired || ssDown.InvokeRequired)
            {
                dlgUpdateDataRepeaterDataSource d = new dlgUpdateDataRepeaterDataSource(UpdateDataIntoFlowLayoutPanel);
                this.Invoke(d, new object[] { datasource });

            }
            else
            {

                _BindingSource.DataSource = null;
                _BindingSource.DataSource = datasource;

                tslNumberOfRecords.Text = datasource.Count.ToString();

                flpMovies.Visible = false;
                flpMovies.Controls.Clear();
                
                foreach (Classes.MovieFeed item in datasource)
                {

                    UserControls.ucResultBlock uc = new UserControls.ucResultBlock();

                    uc.Title = item.Title;
                    uc.Link = item.Link;
                    uc.FileSize = item.FileSize;
                    uc.IMDBLink = item.IMDBLink;
                    uc.MovieName = item.MovieName;
                    uc.MovieYear = item.MovieYear;
                    uc.MovieRate = item.MovieRate;
                    uc.MovieRateColor = item.MovieRateColor;
                    uc.MovieRateVotes = item.MovieRateVotes;
                    uc.MovieImageUrl = item.MovieImageUrl;
                    uc.Description = item.Description;

                    flpMovies.Controls.Add(uc);

                }

                flpMovies.Visible = true;

            }

        }

        private void UpdateProgressBarValue(int percentage)
        {
            if (ssDown.InvokeRequired || ssDown.InvokeRequired)
            {
                dlgUpdateProgressBarVaue d = new dlgUpdateProgressBarVaue(UpdateProgressBarValue);
                this.Invoke(d, new object[] { percentage });

            }
            else
            {
                MainToolStripProgressBar.Value = percentage;
            }
        }

        private void UpdateToolStripText(ToolStripItem ctl, string text)
        {
            if (ctl.Owner.InvokeRequired)
            {
                dlgUpdateToolStripItemText d = new dlgUpdateToolStripItemText(UpdateToolStripText);
                this.Invoke(d, new object[] { ctl, text });

            }
            else
            {
                ctl.Text = text;
            }
        }

        private void PopulateTemplatesSubMenus()
        {

            tsmiSearchTemplates.DropDownItems.Clear();

            foreach (var item in Classes.SystemSettings.SearchTemplateList)
            {
                ToolStripMenuItem tsmi = new ToolStripMenuItem();
                tsmi.Text = item.Name;
                tsmi.Tag = item;
                tsmi.Click += tsmiSearchTemplate_Click;

                if (item.Name == Classes.SystemSettings.SelectedTemplate.Name)
                {
                    tsmi.Checked = true;                    
                }

                tsmiSearchTemplates.DropDownItems.Add(tsmi);
            }
        }

        private void FeedLoader_ProcessChanged(int percentage)
        {
            UpdateProgressBarValue(percentage);
            
            if (percentage != 0)
            {
                int pastSeconds = (DateTime.Now - _LastRefresh.Value).Seconds;
                int remainingSeconds = pastSeconds * (100 - percentage) / percentage;
                UpdateToolStripText(tsslRemainingTime, "Remaining time: " + remainingSeconds + " seconds");
            }

        }

        #endregion

        private delegate void dlgUpdateSearchButton(bool searchFinished);
        private delegate void dlgUpdateDataRepeaterDataSource(List<Classes.MovieFeed> datasource);
        private delegate void dlgUpdateProgressBarVaue(int percentage);
        private delegate void dlgUpdateToolStripItemText(ToolStripItem ctl, string text);

        private System.Timers.Timer tmrAutoRefresh = new System.Timers.Timer();
        private DateTime? _LastRefresh;
        private BindingSource _BindingSource;
        private bool _LoadingData = false;
        private System.Threading.Thread _SearchThread;

    }

}